package org.xiaojl.common.base;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.UriUtils;
import org.xiaojl.common.ResultUtil;
import org.xiaojl.common.SessionUser;
import org.xiaojl.config.easyui.PageBean;
import org.xiaojl.config.easyui.PageParam;
import org.xiaojl.config.mybatisplus.MybatisPlusPageUtil;
import org.xiaojl.utils.StringEscapeEditor;
import org.xiaojl.utils.ToolUtil;
import org.xiaojl.utils.WebUtil;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;

public abstract class BaseController {
	private static final Logger log = LoggerFactory.getLogger(BaseController.class);
	protected HttpServletRequest request;
	protected HttpServletResponse response;
	protected HttpSession session;
	
	/** 异常处理 */
	@ExceptionHandler  
	public Object exp(Exception ex){
		log.error("系统出现异常："+ex.getMessage());
		if(ex instanceof AuthorizationException){
			return ResultUtil.renderError("对不起，您没有该操作的执行权限！");
		}else{
			return ResultUtil.renderError("哎哟喂！系统的脑子有点乱...");
		}
	}
	
	@InitBinder
    public void initBinder(ServletRequestDataBinder binder) {
        /**
         * 自动转换日期类型的字段格式
         */
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
        /**
         * 自动转换日期类型的字段格式
         */
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
        /**
         * 防止XSS攻击
         */
        binder.registerCustomEditor(String.class, new StringEscapeEditor(true, false));
    }
	
	@ModelAttribute
	public void setHttpServletParam(HttpServletRequest request,HttpServletResponse response){
		this.request = request;
		this.response = response;
		this.session = request.getSession();
	}
	
	/**
	 * 获取当前登录用户
	 */
	public SessionUser getSessionUser(){
		SessionUser user = WebUtil.getSessionUser(request);
		return user;
	}
	
	/**
	 * 获取项目路径：D:\xiaojl\opt\tomcats\apache-tomcat-7.0.57-nginx2-28080\webapps\smEasyUI\
	 * @return
	 */
	protected String getContextPath(){
		String basePath = request.getSession().getServletContext().getRealPath("/");
		return basePath;
	}
	
	/**
	 * 查询列表数据（分页）
	 * 
	 * @param pageParam
	 * @param entity
	 * @param baseService
	 * @return
	 */
	protected <E> PageBean<E> selectListPage(PageParam pageParam, E entity, IService<E> baseService) {
		PageBean<E> pageBean = new PageBean<E>(pageParam);
		Page<E> page = MybatisPlusPageUtil.getPage(pageBean);
		
		Page<E> resultPage = null;
		if(ToolUtil.isNotEmpty(entity)){
			if(entity instanceof BaseEntity){
				BaseEntity<E> be = (BaseEntity<E>)entity;
				resultPage = baseService.selectPage(page, be.bindingQueryWrapper());
			}
		}else{
			resultPage = baseService.selectPage(page);
		}
		
		pageBean.setTotal(resultPage.getTotal());
		pageBean.setRows(resultPage.getRecords());
		
		return pageBean;
	}
	
	/**
	 * 跳转到页面
	 * 
	 * @param viewName
	 * @param model
	 * @return
	 */
	protected ModelAndView operatePage(String viewName,Model model) {
		ModelAndView mv = new ModelAndView(viewName);
		mv.addAllObjects(model.asMap());
		return mv;
	}
	
	/**
	 * Ajax失败响应
	 * @param msg
	 * @return
	 */
	protected Object operateError() {
		return operateError("哎哟喂！系统的脑子有点乱...");
	}
	
	/**
	 * Ajax失败响应
	 * @param msg
	 * @return
	 */
	protected Object operateError(String msg) {
		return ResultUtil.renderError(msg);
	}
	
	/**
	 * Ajax成功响应
	 * @param msg
	 * @param obj
	 * @return
	 */
	protected Object operateSuccess(String msg,Object obj) {
		return ResultUtil.renderSuccess(msg, obj);
	}
	
	/**
	 * Ajax成功响应
	 * @param msg
	 * @return
	 */
	protected Object operateSuccess(String msg) {
		return ResultUtil.renderSuccess(msg);
	}
	
    /**
	 * redirect跳转
	 * @param url 目标url
	 */
	protected String redirect(String url) {
		return new StringBuilder("redirect:").append(url).toString();
	}
	
	/**
	 * 下载文件
	 * @param file 文件
	 * @throws UnsupportedEncodingException 
	 */
	protected ResponseEntity<Resource> download(File file) throws UnsupportedEncodingException {
		String fileName = file.getName();
		return download(file, fileName);
	}
	
	/**
	 * 下载
	 * @param file 文件
	 * @param fileName 生成的文件名
	 * @return {ResponseEntity}
	 * @throws UnsupportedEncodingException 
	 */
	protected ResponseEntity<Resource> download(File file, String fileName) throws UnsupportedEncodingException {
		Resource resource = new FileSystemResource(file);
		
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		String header = request.getHeader("User-Agent");
		// 避免空指针
		header = header == null ? "" : header.toUpperCase();
		HttpStatus status;
		if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
			fileName = UriUtils.encode(fileName, StandardCharsets.UTF_8.name());
			status = HttpStatus.OK;
		} else {
			fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
			status = HttpStatus.CREATED;
		}
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		headers.setContentDispositionFormData("attachment", fileName);
		return new ResponseEntity<Resource>(resource, headers, status);
	}

}
